package com.zb.network.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zb.entity.*;
import com.zb.excel.ExcelDynamicsFieldUtil;
import com.zb.excel.converter.WorkConverter;
import com.zb.excel.entity.ExcelDynamicsField;
import com.zb.excel.entity.ExcelDynamicsFieldResult;
import com.zb.extend.NetworkExtend;
import com.zb.extend.NetworkFieldValExtend;
import com.zb.network.service.ConNetworkFieldExportService;
import com.zb.service.*;
import com.zb.utils.ZbManager;
import com.zb.vo.*;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author WEN
 * @Date 2024/3/5 0005
 **/
@Service
public class ConNetworkFieldExportServiceImpl implements ConNetworkFieldExportService {
    /**
     * Excel每页导出数量
     */
    private static long EXCEL_SHEET_DATA_SIZE = 5000;

    @Resource
    private ZjNetworkService networkService;
    @Resource
    private ZjNetworkTypeService networkTypeService;
    @Resource
    private ZjNetworkStrategyService networkStrategyService;
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ZjNetworkFieldValService networkFieldValService;

    @Resource
    private ZjNetworkModuleSettlementService networkModuleSettlementService;
    @Resource
    private ZjWorkModuleService workModuleService;
    // 保存并导出服务商字段
    @Override
    public void networkExportField(HttpServletResponse response, AccounLoginInfo loginInfo, NetworkExportAndSaveFieldVo exportFieldVo) {
        long totalCount = networkService.getListCount(loginInfo.getCustAccId(), exportFieldVo.getNetworkSelectVo());
        Assert.isTrue(totalCount > 0, "当前没有可导出的服务商数据");
        // 服务商系统字段
        Map<String, String> networkSysField = ExportFieldAttrVo.exportFieldAttrToMap(1, exportFieldVo.getExportFieldVo().getFieldAttrs());
        // 服务商自定义字段
        Map<String, String> networkCustomField = ExportFieldAttrVo.exportFieldAttrToMap(2, exportFieldVo.getExportFieldVo().getFieldAttrs());
        long totalPage = totalCount % EXCEL_SHEET_DATA_SIZE == 0? totalCount / EXCEL_SHEET_DATA_SIZE : totalCount / EXCEL_SHEET_DATA_SIZE +1;
        long page = 1;
        exportFieldVo.getNetworkSelectVo().setLimit(EXCEL_SHEET_DATA_SIZE);
        List<Map<String, Object>> mapList = null;
        List<List<ExcelDynamicsField>> excelDynamicsFieldList = null;
        ExcelDynamicsFieldResult dynamicsFieldResult = null;
        ArrayList<List<String>> excelHeader = new ArrayList<>();
        List<List<List<String>>> excelDataList = new ArrayList<>();
        while (page <= totalPage) {
            exportFieldVo.getNetworkSelectVo().setPage(page);
            mapList = handlerNetworkExportData(loginInfo, exportFieldVo.getNetworkSelectVo(), networkSysField, networkCustomField);
            //过滤服务商结算价字段
            List<ExportFieldAttrVo> filteredFieldAttrs = exportFieldVo.getExportFieldVo().getFieldAttrs().stream()
                    .filter(attr -> !"network_settlement_price".equals(attr.getValue()))
                    .collect(Collectors.toList());
//            excelDynamicsFieldList = handlerResultData(mapList, exportFieldVo.getExportFieldVo().getFieldAttrs());
            excelDynamicsFieldList = handlerResultData(mapList, filteredFieldAttrs);
            dynamicsFieldResult = ExcelDynamicsFieldUtil.excelDynamicsFieldPack(excelDynamicsFieldList);
            if (CollectionUtil.isEmpty(excelHeader)) {
                excelHeader.addAll(dynamicsFieldResult.getExcelHeader());
            }
            excelDataList.add(dynamicsFieldResult.getExcelData());
            page++;
        }
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(response.getOutputStream()).head(excelHeader).build();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        int sheetNo = 1;
        for (List<List<String>> lists : excelDataList) {
//            excelWriter.write(lists, EasyExcel.write().sheet(sheetNo, "No." + sheetNo)
              excelWriter.write(lists, EasyExcel.write().sheet(sheetNo, "服务商信息_" + sheetNo)
                    // 设置导出的列宽
                    .registerWriteHandler(new AbstractHeadColumnWidthStyleStrategy() {
                        @Override
                        protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
                            boolean columWidth = isHead || CollectionUtil.isNotEmpty(cellDataList);
                            if (columWidth) {
                                Sheet sheet = writeSheetHolder.getSheet();
                                for (int i = 0; i < excelHeader.size(); i++) {
                                    sheet.setColumnWidth(i, 5000);
                                }
                            }
                        }
                        @Override
                        protected Integer columnWidth(Head head, Integer integer) {
                            return null;
                        }
                    })
                    .build());
            sheetNo++;
        }
            // 1. 查询所有服务商
            List<NetworkExtend> networkList = networkService.getListExtend(loginInfo.getCustAccId(), exportFieldVo.getNetworkSelectVo());
            // 2. 组装结算价管理sheet数据
            List<NetworkSettlementExportVo> settlementExportList = new ArrayList<>();
            for (NetworkExtend vo : networkList) {
                List<ZjNetworkModuleSettlement> priceList = networkModuleSettlementService.list(
                        new QueryWrapper<ZjNetworkModuleSettlement>().eq("network_id", vo.getId())
                );
                List<ZjWorkModule> moduleList = workModuleService.getPartInfoByIds(
                        priceList.stream().map(ZjNetworkModuleSettlement::getModuleId).toList()
                );
                Map<Long, ZjWorkModule> moduleMap = moduleList.stream()
                        .collect(Collectors.toMap(ZjWorkModule::getId, m -> m));
                if (CollectionUtil.isEmpty(priceList)) {
                    NetworkSettlementExportVo exportVo = new NetworkSettlementExportVo();
                    exportVo.setNetworkName(vo.getName());
                    exportVo.setModuleName("");
                    exportVo.setSettlementPrice(null);
                    exportVo.setCreateTime(null);
                    exportVo.setUpdateTime(null);
                    settlementExportList.add(exportVo);
                } else {
                    for (ZjNetworkModuleSettlement p : priceList) {
                        ZjWorkModule module = moduleMap.get(p.getModuleId());
                        NetworkSettlementExportVo exportVo = new NetworkSettlementExportVo();
                        exportVo.setNetworkName(vo.getName());
                        exportVo.setModuleName(module != null ? module.getName() : "");
                        exportVo.setSettlementPrice(p.getPrice());
                        exportVo.setCreateTime(p.getGmtCreate());
                        exportVo.setUpdateTime(p.getGmtUpdate());
                        settlementExportList.add(exportVo);
                    }
                }
            }
            // 写结算价管理sheet
            int totalSettlementPages = (int) Math.ceil((double) settlementExportList.size() / EXCEL_SHEET_DATA_SIZE);
            for (int i = 0; i < totalSettlementPages; i++) {
                int start = i * (int) EXCEL_SHEET_DATA_SIZE;
                int end = Math.min(start + (int) EXCEL_SHEET_DATA_SIZE, settlementExportList.size());
                List<NetworkSettlementExportVo> subList = settlementExportList.subList(start, end);

                WriteSheet settlementSheet = EasyExcel.writerSheet(sheetNo++, "服务商结算价管理_" + (i + 1))
                        .head(NetworkSettlementExportVo.class)
                        .registerWriteHandler(new AbstractHeadColumnWidthStyleStrategy() {
                            @Override
                            protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
                                if (isHead || CollectionUtil.isNotEmpty(cellDataList)) {
                                    Sheet sheet = writeSheetHolder.getSheet();
                                    for (int col = 0; col < excelHeader.size(); col++) {
                                        sheet.setColumnWidth(col, 5000);
                                    }
                                }
                            }

                            @Override
                            protected Integer columnWidth(Head head, Integer integer) {
                                return null;
                            }
                        })
                        .build();
                excelWriter.write(subList, settlementSheet);
            }
//            WriteSheet settlementSheet = EasyExcel.writerSheet(sheetNo, "服务商结算价管理")
//                    .head(NetworkSettlementExportVo.class)
//                    // 设置导出的列宽
//                    .registerWriteHandler(new AbstractHeadColumnWidthStyleStrategy() {
//                        @Override
//                        protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
//                            boolean columWidth = isHead || CollectionUtil.isNotEmpty(cellDataList);
//                            if (columWidth) {
//                                Sheet sheet = writeSheetHolder.getSheet();
//                                for (int i = 0; i < excelHeader.size(); i++) {
//                                    sheet.setColumnWidth(i, 5000);
//                                }
//                            }
//                        }
//
//                        @Override
//                        protected Integer columnWidth(Head head, Integer integer) {
//                            return null;
//                        }
//                    })
//                    .build();
//            excelWriter.write(settlementExportList, settlementSheet);
        try {
            // 注：如使用中文，则需要此行代码配置，如仅使用字母，则可要可不要
            response.addHeader("Content-Disposition", "filename=network_"+ DateFormatUtils.format(new Date(), "yyyyMM") +".xlsx");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            excelWriter.finish();
        } catch (Exception e) {
            ZbManager.log.error("服务商数据导出异常：" + e.getMessage());
        }
    }

    private List<List<ExcelDynamicsField>> handlerResultData(List<Map<String, Object>> mapList, List<ExportFieldAttrVo> fieldAttrs) {
        List<List<ExcelDynamicsField>> excelDynamicsFieldList = new ArrayList<>();
        List<ExcelDynamicsField> dynamicsFieldList = null;
        for (Map<String, Object> map : mapList) {
            dynamicsFieldList = new ArrayList<>();
            for (ExportFieldAttrVo attr : fieldAttrs) {
                dynamicsFieldList.add(new ExcelDynamicsField(attr.getName(), map.get(attr.getType() + "_" + attr.getValue())));
            }
            excelDynamicsFieldList.add(dynamicsFieldList);
        }
        return excelDynamicsFieldList;
    }



    public List<Map<String, Object>> handlerNetworkExportData(AccounLoginInfo loginInfo, NetworkSelectVo networkSelectVo, Map<String, String> networkSysField, Map<String, String> networkCustomField) {
        List<Map<String, Object>> resultMapList = new ArrayList<>();
        List<NetworkExtend> networkList = networkService.getListExtend(loginInfo.getCustAccId(), networkSelectVo);
        // 服务商分类
        List<ZjNetworkType> typeList = new ArrayList<>();
        if (null != networkSysField.get("network_type")) {
            typeList.addAll(networkTypeService.listByIds(networkList.stream().map(NetworkExtend::getNetworkTypeId).distinct().toList()));
        }
        // 服务商接单策略
        List<ZjNetworkStrategy> strategyList = new ArrayList<>();
        if (null != networkSysField.get("receiving_order_strategy")) {
            strategyList.addAll(networkStrategyService.listByIds(networkList.stream().map(NetworkExtend::getId).distinct().toList()));
        }
        // 全部工单
        List<QtyVo> totalOrderQtyVos = new ArrayList<>();
        if (null != networkSysField.get("total_order_count")) {
            totalOrderQtyVos.addAll(workOrderService.getTotalOrderByNetworkIds(networkList.stream().map(NetworkExtend::getId).distinct().toList()));
        }
        // 服务商自定义字段
        List<NetworkFieldValExtend> valExtendList = new ArrayList<>();
        if (null != networkCustomField) {
            valExtendList.addAll(networkFieldValService.getByNetworkIds(networkList.stream().map(NetworkExtend::getId).distinct().toList()));
        }
        Map<String, Object> map  = null;
        for (NetworkExtend vo : networkList) {
            map = new HashMap<>();
            getNetworkSysFieldData(map, networkSysField, vo);
            if (CollectionUtil.isNotEmpty(typeList)) {
                map.put("1_" + "network_type", typeList.stream().filter(f -> Objects.equals(f.getId(), vo.getNetworkTypeId())).findFirst().map(ZjNetworkType::getName).orElse(""));
            }
            if (CollectionUtil.isNotEmpty(strategyList)) {
                map.put("1_" + "receiving_order_strategy", strategyList.stream().filter(f -> Objects.equals(f.getId(), vo.getId())).findFirst()
                        .map(ZjNetworkStrategy::getAutoSureReceiveOrder).orElse(true)? "自动确认接单" : "手动确认接单");
            }
            if (CollectionUtil.isNotEmpty(totalOrderQtyVos)) {
                map.put("1_" + "total_order_count", totalOrderQtyVos.stream().filter(f -> Objects.equals(f.getId(), vo.getId())).map(QtyVo::getQty).findFirst().orElse(0).toString());
            }
            // 服务商自定义字段
            if (CollectionUtil.isNotEmpty(valExtendList)) {
                getNetworkCustomFieldData(map, vo.getId(), valExtendList);
            }
            resultMapList.add(map);
        }
        return resultMapList;
    }

    /**
     * 获取服务商系统字段数据
     * @param map
     * @param networkSysField
     * @param vo
     */
    public void getNetworkSysFieldData(Map<String, Object> map, Map<String, String> networkSysField, NetworkExtend vo) {
        if (null != networkSysField.get("name")) {
            map.put("1_" + "name", vo.getName());
        }
        if (null != networkSysField.get("status")) {
            map.put("1_" + "status", vo.getDisabled()? "禁用" : "启用");
        }
        if (null != networkSysField.get("team_type")) {
            map.put("1_" + "team_type", vo.getTeamType() == 1? "团队" : "个人");
        }
        if (null != networkSysField.get("category")) {
            map.put("1_" + "category", vo.getCategory() == 1? "内部服务商" : "外部服务商");
        }
        if (null != networkSysField.get("network_manager_emp")) {
            map.put("1_" + "network_manager_emp", vo.getManagerUserName());
        }
        if (null != networkSysField.get("network_manager_emp_phone")) {
            map.put("1_" + "network_manager_emp_phone", vo.getManagerUserPhone());
        }
        if (null != networkSysField.get("network_address")) {
            map.put("1_" + "network_address", new StringBuffer(vo.getProvince()).append("-")
                    .append(vo.getCity()).append("-")
                    .append(vo.getArea()).append("-")
                    .append(vo.getAddress())
            );
        }
    }

    /**
     * 获取服务商自定义导出字段
     * @param map
     * @param networkId
     * @param valExtendList
     */
    public void getNetworkCustomFieldData(Map<String, Object> map, Long networkId, List<NetworkFieldValExtend> valExtendList) {
        valExtendList.stream().filter(f -> Objects.equals(f.getNetworkId(), networkId)).forEach(val -> {
            map.put("2_" + val.getNetworkFieldId(), String.join("、", val.getValues()));
        });
    }

}
